home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / wdj0697.zip / WIESMAN.ZIP / DIALCTRL.CPP < prev    next >
C/C++ Source or Header  |  1997-01-20  |  6KB  |  252 lines

  1. // DialCtrl.cpp : implementation file
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include "CustCtrl.h"
  6. #include "DialCtrl.h"
  7. #include "math.h"
  8.  
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14.  
  15. /////////////////////////////////////////////////////////////////////////////
  16. // CDialControl
  17.  
  18. CDialControl::CDialControl()
  19. {
  20.     m_nMin = 0;
  21.     m_nMax = 20;
  22.     m_nValue = 0;
  23.     m_nRate = 1;
  24.     m_bDragging = FALSE;
  25. }
  26.  
  27. CDialControl::~CDialControl()
  28. {
  29. }
  30.  
  31.  
  32. BEGIN_MESSAGE_MAP(CDialControl, CWnd)
  33.     //{{AFX_MSG_MAP(CDialControl)
  34.     ON_WM_PAINT()
  35.     ON_WM_SETFOCUS()
  36.     ON_WM_KILLFOCUS()
  37.     ON_WM_LBUTTONDOWN()
  38.     ON_WM_KEYDOWN()
  39.     ON_WM_GETDLGCODE()
  40.     ON_WM_MOUSEMOVE()
  41.     ON_WM_LBUTTONUP()
  42.     //}}AFX_MSG_MAP
  43. END_MESSAGE_MAP()
  44.  
  45.  
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CDialControl message handlers
  48.  
  49. void CDialControl::OnPaint() 
  50. {
  51.     CPaintDC dc(this); // device context for painting
  52.     
  53.     CRect rect;
  54.     GetClientRect(&rect);
  55.     int nDialRadius = min(rect.Width(), rect.Height()) / 2 - 12;
  56.     CPoint ptCenter = rect.CenterPoint();
  57.     CRect rectCircle(ptCenter.x - nDialRadius, ptCenter.y - nDialRadius,
  58.                      ptCenter.x + nDialRadius, ptCenter.y + nDialRadius);
  59.  
  60.     CDC dcMem, dcTemp;
  61.     dcTemp.CreateCompatibleDC(&dc);    // temp dc for rendering
  62.     CBitmap bitmap, *pTempOld;
  63.     bitmap.CreateCompatibleBitmap(&dc, rect.Width(), rect.Height());
  64.     pTempOld = dcTemp.SelectObject(&bitmap);
  65.  
  66.     // now do rendering
  67.     CBrush brush(GetSysColor(COLOR_BTNFACE));
  68.     CBrush *pOldBrush;
  69.     CPen *pOldPen;
  70.     CPen penThickBlack(PS_SOLID, 2, RGB(0, 0, 0));
  71.     CPen penThickGray(PS_SOLID, 2, RGB(128, 128, 128));
  72.     CPen penGray(PS_SOLID, 1, RGB(128, 128, 128));
  73.     CPen penBlack(PS_SOLID, 1, RGB(0, 0, 0));
  74.  
  75.     dcTemp.FillRect(&rect, &brush);
  76.  
  77.     pOldBrush = dcTemp.SelectObject(&brush);
  78.     if(IsWindowEnabled())
  79.     {
  80.         pOldPen = dcTemp.SelectObject(&penThickBlack);
  81.     }
  82.     else
  83.     {
  84.         pOldPen = dcTemp.SelectObject(&penThickGray);
  85.     }
  86.     dcTemp.Ellipse(&rectCircle);
  87.     
  88.     if(IsWindowEnabled())
  89.     {
  90.         dcTemp.SelectObject(&penBlack);
  91.     }
  92.     else
  93.     {
  94.         dcTemp.SelectObject(&penGray);
  95.     }
  96.  
  97.     // draw min and max lines
  98.     CPoint point1, point2;
  99.  
  100.     GetLinePoints(nDialRadius + 12, 0, point1, point2);
  101.     dcTemp.MoveTo(ptCenter + point1);
  102.     dcTemp.LineTo(ptCenter + point2);
  103.  
  104.     GetLinePoints(nDialRadius + 12, 100, point1, point2);
  105.     dcTemp.MoveTo(ptCenter + point1);
  106.     dcTemp.LineTo(ptCenter + point2);
  107.  
  108.     // now draw value line
  109.     int nPercent = (m_nValue - m_nMin) * 100 / (m_nMax - m_nMin);
  110.     GetLinePoints(nDialRadius, nPercent, point1, point2);
  111.     dcTemp.MoveTo(ptCenter + point1);
  112.     dcTemp.LineTo(ptCenter + point2);
  113.  
  114.     dcTemp.SelectObject(pOldPen);
  115.     dcTemp.SelectObject(pOldBrush);
  116.     
  117.     if(GetFocus() == this)
  118.         dcTemp.DrawFocusRect(&rect);
  119.  
  120.     // now back to the real dc
  121.     dc.BitBlt(0, 0, rect.Width(), rect.Height(), &dcTemp, 0, 0, SRCCOPY);
  122.     dcTemp.SelectObject(pTempOld);
  123. }
  124.  
  125. void CDialControl::OnSetFocus(CWnd* pOldWnd) 
  126. {
  127.     CWnd::OnSetFocus(pOldWnd);
  128.     
  129.     Invalidate();
  130.     
  131. }
  132.  
  133. void CDialControl::OnKillFocus(CWnd* pNewWnd) 
  134. {
  135.     CWnd::OnKillFocus(pNewWnd);
  136.     
  137.     Invalidate();
  138.     
  139. }
  140.  
  141. void CDialControl::OnLButtonDown(UINT nFlags, CPoint point) 
  142. {
  143.     SetFocus();
  144.  
  145.     m_bDragging = TRUE;
  146.     SetCapture();
  147.     CalculateValFromPoint(point);    
  148.     CWnd::OnLButtonDown(nFlags, point);
  149. }
  150.  
  151. void CDialControl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  152. {
  153.     if(nChar == VK_DOWN)
  154.     {
  155.         int nNewVal = max(m_nMin, m_nValue - m_nRate * (int)nRepCnt);
  156.         if(nNewVal != m_nValue)
  157.         {
  158.             m_nValue = nNewVal;
  159.             Invalidate();
  160.             
  161.             WPARAM wToSend = MAKELONG(GetDlgCtrlID(), DN_DOWN);
  162.             LPARAM lToSend = (LPARAM)GetSafeHwnd();
  163.  
  164.             GetParent()->SendMessage(WM_COMMAND, wToSend, lToSend);
  165.         }
  166.         return;
  167.     }
  168.     if(nChar == VK_UP)
  169.     {
  170.         int nNewVal = min(m_nMax, m_nValue + m_nRate * (int)nRepCnt);
  171.         if(nNewVal != m_nValue)
  172.         {
  173.             m_nValue = nNewVal;
  174.             Invalidate();
  175.             WPARAM wToSend = MAKELONG(GetDlgCtrlID(), DN_UP);
  176.             LPARAM lToSend = (LPARAM)GetSafeHwnd();
  177.  
  178.             GetParent()->SendMessage(WM_COMMAND, wToSend, lToSend);
  179.         }
  180.         return;
  181.     }
  182.     
  183.     CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  184. }
  185.  
  186. void CDialControl::GetLinePoints(int nLength, int nPercent, CPoint &point1, CPoint &point2)
  187. {
  188.     double pi = 3.1415926535;
  189.     double dStartRads = 1.25 * pi;
  190.     double dOffsetRads = 1.5 * pi * (double)(nPercent)/100.0;
  191.     double radians = dStartRads - dOffsetRads;
  192.     point1.x = (int)(cos(radians) * (nLength - 2));
  193.     point1.y = -(int)(sin(radians) * (nLength - 2));
  194.     point2.x = (int)(cos(radians) * (nLength - 10));
  195.     point2.y = -(int)(sin(radians) * (nLength - 10));
  196. }
  197.  
  198. UINT CDialControl::OnGetDlgCode() 
  199. {
  200.     return CWnd::OnGetDlgCode() | DLGC_WANTARROWS;
  201. }
  202.  
  203. void CDialControl::OnMouseMove(UINT nFlags, CPoint point) 
  204. {
  205.     if(m_bDragging)
  206.         CalculateValFromPoint(point);
  207.     CWnd::OnMouseMove(nFlags, point);
  208. }
  209.  
  210. void CDialControl::CalculateValFromPoint(CPoint point)
  211. {
  212.     CRect rect;
  213.     GetClientRect(&rect);
  214.     CPoint pointCenter = rect.CenterPoint();
  215.     CPoint pointDiff = pointCenter - point;
  216.     double pi = 3.1415926535;
  217.     double dCos = (double)pointDiff.x / sqrt((double)(pointDiff.x * pointDiff.x + pointDiff.y * pointDiff.y));
  218.     double dRads = acos(dCos);
  219.     if(pointDiff.y <= 0)
  220.         dRads += pi;
  221.  
  222.     double dOffsetRads = 1.25 * pi - dRads;
  223.     if(dOffsetRads < 0)
  224.         dOffsetRads += 2 * pi;
  225.     
  226.     if(dOffsetRads > 1.5 * pi && dOffsetRads < 1.75 * pi)
  227.         dOffsetRads = 1.5 * pi;
  228.     if(dOffsetRads > 1.75 * pi)
  229.         dOffsetRads = 0;
  230.     double dPercent = dOffsetRads / (1.5 * pi);
  231.     if(pointDiff.y > 0)
  232.         dPercent = 1.0 - dPercent;
  233.  
  234.     int nNewVal = m_nMin + (int)(dPercent * (m_nMax - m_nMin)); 
  235.     if(nNewVal != m_nValue)
  236.     {
  237.         m_nValue = nNewVal;
  238.         Invalidate();
  239.         WPARAM wToSend = MAKELONG(GetDlgCtrlID(), DN_CLICK);
  240.         LPARAM lToSend = (LPARAM)GetSafeHwnd();
  241.  
  242.         GetParent()->SendMessage(WM_COMMAND, wToSend, lToSend);
  243.     }
  244. }
  245.  
  246. void CDialControl::OnLButtonUp(UINT nFlags, CPoint point) 
  247. {
  248.     m_bDragging = FALSE;
  249.     ReleaseCapture();    
  250.     CWnd::OnLButtonUp(nFlags, point);
  251. }
  252.